<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    老陈说this指向
</body>
</html>
<script>
 // 在普通函数中，this 指向的是 window
// var username = 'cn'
// function fn() {
//   console.log(this);
//   alert(this.username) //cn
// }
// fn()

// 有一点需要注意，let 声明的全局变量，不是指向 window 对象

// 对象的函数调用，this指向的是调用函数的对象

// var b = 2222
// let obj = {
//   a: 111,
//   fn: function() {
//     console.log(this);
//     alert(this.a) //111
//     alert(this.b) //undefined
//   }
// }
// obj.fn()

// 在构造函数中，this 指向 实例化出来的对象；

// function Star(name) {
//   this.name = name;
//   this.fn = () => {
//     console.log(this);
//   }
// }

// let obj = new Star('张三');
// obj.fn();
// // console.log(obj);
// let obj1 = new Star('李四');
// obj1.fn();


// 在箭头函数中，this 指向，只和声明箭头函数的作用域的this指向有关

// let obj = {
//   A () {
//     console.log(this);
//     return () => {
//       return this
//     }
//   },
//   B () {
//     return function () {
//       return this
//     }
//   }
// }

// let func = obj.A()
// console.log(func() === obj) // true

// func = obj.B()
// console.log(func() === obj) // false
// console.log(func() === window) // true


// let obj = { 
//   name: '貂蝉',
//   jump: function () {
//     console.log(this);
//     setTimeout(function () {
//         console.log(this);
//     },1000)
//   }
// }

// obj.jump();



// apply、call、bind 可以改变this 指向；



// function Fruits() {
//    this.color = 'red';
// } // 构造函数

// // prototype 原型
// Fruits.prototype = {
//   say: function() {
//     console.log('My color is ' + this.color)
//   }
// }

// var apple = new Fruits();
// // console.log(apple);
// apple.say() //My color is red

// // 但是如果我们有一个对象banana= {color : "yellow"} ,我们不想对它重新定义 say 方法，
// //那么我们可以通过 call 或 apply 用 apple 的 say 方法：
// let banana = {
//   color: 'yellow'
// }
// apple.say.call(banana) //My color is yellow
// apple.say.apply(banana) //My color is yellow

// 对于 apply、call 二者而言，作用完全一样，只是接受参数的方式不太一样
// func.call(this, arg1, arg2)
// func.apply(this, [arg1, arg2])

// let obj = {
//   num: 10,
//   num1: 11,
//   add: function(val,val1){
//     console.log(this.num + this.num1+val+val1);
//   }
// }


// let obj1 = {
//   num: 100,
//   num1: 50,
//   add: function(val,val1){
//     console.log(this.num + this.num1+val+val1);
//   }
// }

// obj.add.apply(obj1,[1,2]);

// obj.add.call(obj1,1,2);

// bind() 可以改变this指向，和 call, apply 的区别在于 bind 不会立即调用，call, apply会立即调用

// let bindfn = obj.add.bind(obj1);
// bindfn(1,2)



let obj = { 
  name: '貂蝉',
  jump: function () {
    console.log(this);
    setTimeout(function () { // 需求让this 指向 obj 不能使用箭头函数
        console.log(this);
    }.bind(this),1000)
  }
}
obj.jump();



// function fn () {
//   console.log(this.name);
// }

// fn.bind(obj);




// let start = {
//   name: '快乐风男',
//   doing:function(val) {
//     console.log(this.name+'亮亮疾风吧');
//     console.log(val);
//   }
// }
// let start1 = {
//   name: '塞拉斯',
//   doing:function(val) {
//     console.log(this.name+'亮亮疾风吧');
//     console.log(val);
//   }
// }

// 需求 用start1 调用 doing 的时候 打印出来 快乐风男亮亮疾风吧
// start.doing();
// start1.doing();

// start1.doing.call(start,'闪现');
// start1.doing.apply(start,['闪现']);


// bind 去改变this指向的时候，返回的就是一个函数，没有立即调用
// start1.doing.bind(start);
// let bindFt = start1.doing.bind(start);
// bindFt('闪现')
// console.log(bindFt);
</script>